import math
from typing import List

# from algs.interpolation import get_test_data

from common.params import SoftParams
from model.soft.soft_common import AxialForceResult, data_init
from model.soft.fluid_resistance import tool_pull_fluid, cable_pull_fluid


# 计算上提的张力
# cur 当前节点 d
# pre 上次迭代所计算的节点 d+1
# D 全井深
def calc_uni(params: SoftParams, cur: AxialForceResult, pre: AxialForceResult,
             _list_: List[AxialForceResult]) -> AxialForceResult:
    # 本次计算全井深度
    D: float = _list_[-1].depth
    # 测井仪器的单位浮重
    w1: float = params.w1
    # 电缆的单位浮重
    w2: float = params.w2
    # 先根据上一个节点的值,计算出来当前的 f
    factor_b: float = math.cos(math.radians(pre.inclination))
    # 根据 f 再计算出 n
    # if cur.depth == D:
    #     cur.F = 0.0
    if 0 <= cur.depth < D:
        f: float = w2 * factor_b + params.get_mu_pull(cur.depth) * pre.N + pre.F
        cur.F = f
        n: float = calc_n(D, params, cur)
        cur.N = n
    # print("从{}开始迭代到当前深度{}的CF:{}, CN: {},PF: {}, PN: {}".format(D, cur.depth, cur.F, cur.N, pre.F, pre.N))
    return cur


# 基于当前节点求解N
# cur.F 已知
def calc_n(D: float, params: SoftParams, cur: AxialForceResult) -> float:
    # 测井仪器的单位浮重
    w1: float = params.w1
    # 电缆的单位浮重
    w2: float = params.w2

    factor_a: float = cur.azimuth_rate
    factor_b: float = math.sin(math.radians(cur.inclination))
    factor_c: float = cur.inclination_rate
    # 大于等于 0 @TODO
    if (cur.depth > 0) and (cur.depth <= D):
        factor_d: float = cur.F * factor_a * factor_b
        factor_e: float = cur.F * factor_c
        n: float = math.sqrt(math.pow(factor_d, 2) + math.pow(factor_e + w2 * factor_b, 2))
        return n
    return 0.0


# 轴力迭代数据
def pull_tension_build(params: SoftParams, _list_: List[AxialForceResult], is_Not_add_resistance: bool) -> List[AxialForceResult]:
    # 长度
    data_len = len(_list_)
    # 本次迭代深度 -1 就是取最后一个
    D: float = _list_[-1].depth
    # 计算正常上提和下放所有深度点的液体阻力
    base_val: int = round((params.F_weak_low + params.F_weak_high) / 8.9)
    rate: float = round(params.F_weak_rate_low / params.F_weak_low, 2)
    _list_[-1].F = base_val * 4.45 * rate
    # N 的值需要基于 F 算出来
    _list_[-1].N = calc_n(D, params, _list_[-1])

    for i in range(data_len - 2, -1, -1):
        _list_[i] = calc_uni(params, _list_[i], _list_[i + 1], _list_)
    # 这个是计算全部井深的 按照对应井深进行相加
    # fluid_resistances_pull = {}
    # for idx in range(int(params.L1), data_len, 1):
    #     fluid_resistances_pull[_list_[idx].depth] = tool_pull_fluid(params, _list_[idx]) + cable_pull_fluid(params, _list_[idx])
    # for i_item in range(len(_list_)):
    #     depth = _list_[i_item].depth
    #     if depth in fluid_resistances_pull:
    #         _list_[i_item].F += fluid_resistances_pull[depth]
    # 现在需要计算的是只有2100位置的液体阻力 和 0米位置的张力进行相加
    fluid_resistances_pull = {}
    fluid_resistances_pull[_list_[-1].depth] = tool_pull_fluid(params, _list_[-1]) + cable_pull_fluid(params, _list_[-1])
    # 在此处加判断
    if is_Not_add_resistance == True:
        _list_[0].F += fluid_resistances_pull[_list_[-1].depth]

    return _list_


# 执行获取计算结果 & 只需要从最大深度开始迭代的结果
def run(params: SoftParams, _list_, is_Not_add_resistance: bool) -> List[AxialForceResult]:
    # 数据预处理
    result_arr: List[AxialForceResult] = data_init(_list_)
    result: List[AxialForceResult] = pull_tension_build(params, result_arr, is_Not_add_resistance)

    return result



